﻿//  Copyright © 2009-2010 by Rhy A. Mednick
//  All rights reserved.
//  http://rhyduino.codeplex.com
//  
//  Redistribution and use in source and binary forms, with or without modification, 
//  are permitted provided that the following conditions are met:
//  
//  * Redistributions of source code must retain the above copyright notice, this list 
//    of conditions and the following disclaimer.
//  
//  * Redistributions in binary form must reproduce the above copyright notice, this 
//    list of conditions and the following disclaimer in the documentation and/or other 
//    materials provided with the distribution.
//  
//  * Neither the name of Rhy A. Mednick nor the names of its contributors may be used 
//    to endorse or promote products derived from this software without specific prior 
//    written permission.
//  
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
//  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
//  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
//  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
//  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
//  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Rhyduino.Message;

namespace Rhyduino.Test.Functionality
{
    public partial class MainForm : Form
    {
        private readonly ProgressBar[] _analogPinValues;
        private readonly Arduino _arduino;

        public MainForm()
        {
            InitializeComponent();
            _arduino = new Arduino("COM3");
            //_arduino = new Arduino();
            _analogPinValues = new[] {pb0, pb1, pb2, pb3, pb4, pb5};
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            // put pin digital pin 6 into pwm mode. We'll use this to visualize the changes that show up
            // on the analog pin we're monitoring.
            _arduino.DigitalPins[6].SetPinMode(PinMode.Pwm);

            _arduino.AnalogPinReportReceived += AnalogPinReportReceivedHandler;
            for (var i = 0; i < 6; i++)
            {
                _arduino.AnalogPins[i].Monitor = false;
            }
            _arduino.AnalogPins[5].Monitor = true;

            //_updateChartDelegate = UpdateChart;
        }

        private void AnalogPinReportReceivedHandler(object sender, FirmataEventArgs<AnalogPinReport> message)
        {
            var pinReport = message.Data;
            var value = 0;
            var ctr = 1;
            //if (pinReport.Pin == 5) 
            //    value = pinReport.Value;

            foreach (var val in _arduino.AnalogPins[5].GetCachedValues().Reverse().TakeWhile(val => ctr <= 10))
            {
                value += val;
                ctr++;
            }

            value = value/ctr;
            if (value > 255)
                value = 255;

            _arduino.DigitalPins[6].SetPinValue(value);
        }

        private void UpdateChart(int pin, int value)
        {
            _analogPinValues[pin].Value = value;
        }

        private void Button1Click(object sender, EventArgs e)
        {
            label1.Text = _arduino.AnalogPins[5].GetCachedValues().Count().ToString();

            Task.Factory.StartNew(Flow);
        }

        private void Flow()
        {
            _arduino.DigitalPins[3].SetPinMode(PinMode.Pwm);
            for (var i = 0; i < 255; i++)
            {
                _arduino.DigitalPins[3].SetPinValue(i);
                Thread.Sleep(20);
            }
            for (var i = 255; i > 0; i--)
            {
                _arduino.DigitalPins[3].SetPinValue(i);
                Thread.Sleep(20);
            }
        }
    }
}